x86/hvm: Fix mapping corner case during task switching
authorAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 1 Aug 2018 13:48:33 +0000 (13:48 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 3 Sep 2018 18:02:36 +0000 (19:02 +0100)
commita9a2a761f75126d908612c64fabe6adde2b6d2b9
tree974353a61ac270457b6ef5e6404e544f6e9a1ba1
parent1f0598a1beb6bbaa838dec4f321af543d3b96c7a
x86/hvm: Fix mapping corner case during task switching

hvm_map_entry() can fail for a number of reasons, including for a misaligned
LDT/GDT access which crosses a 4K boundary.  Architecturally speaking, this
should be fixed, but Long Mode doesn't support task switches, and no 32bit OS
is going to misalign its LDT/GDT base, which is why this task isn't very high
on the TODO list.

However, the hvm_map_fail error label returns failure without raising an
exception, which interferes with hvm_task_switch()'s exception tracking, and
can cause it to finish and return to guest context as if the task switch had
completed successfully.

Resolve this corner case by folding all the failure paths together, which
causes an hvm_map_entry() failure to result in #TS[SEL].  hvm_unmap_entry()
copes fine with a NULL pointer so can be called unconditionally.

In practice, this is just a latent corner case as all hvm_map_entry() failures
crash the domain, but it should be fixed nevertheless.

Finally, rename hvm_load_segment_selector() to task_switch_load_seg() to avoid
giving the impression that it is usable for general segment loading.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Acked-by: Jan Beulich <jbeulich@suse.com>
xen/arch/x86/hvm/hvm.c